OK, use 7,564,263.
I'm tempted to end my reply there, but I guess some explanation is in order.
Suppose for a moment that your my_fn function was going to be used in a single executable so that the semaphore would only need to syncronize among simultaneous instances of that single executable. In that case, you could go ahead and use the address of the function. But what is magic about that address? The loader could, in theory, put another function in another executable at the same address.
There are billions of possible key values, but I have never seen a system that needs more than a few dozen. That makes this a small problem. Just pick something and go with that. It's like picking a name for your function or picking a file name.
Collisions are possible and you should be ready for them. Always test your return codes. And I would put the value in a config file and read it once. This makes it easy to change if that is ever needed. The my_fn could do this internally by using a static value initialized to zero. If zero, read the value and store it in the static variable.
Or you can just store the key as a constant in my_fn and risk the need to recompile should a collision occur. I've done that too.
There is also a function called ftok() that you should look at. It takes a pathname and a small integer and returns a key. I never use it, but if I don't mention it, someone else will.